package com.dream.wukong.common.core.jdbc.sqltemplate.impl;

import com.dream.wukong.common.core.jdbc.sqlconfig.SqlConfig;
import com.dream.wukong.common.core.jdbc.sqlconfig.SqlMapper;
import com.dream.wukong.common.core.jdbc.sqltemplate.SqlTemplate;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author: wuyichao
 * @Description:
 * @Date: Created in 10:21 2018/9/18.
 * @Modified:
 */
public abstract class BaseSqlTemplate implements SqlTemplate, InitializingBean {

    protected SqlConfig sqlConfig   ;

    public SqlConfig getSqlConfig() {
        return sqlConfig;
    }

    public void setSqlConfig(SqlConfig sqlConfig) {
        this.sqlConfig = sqlConfig;
    }


    public SqlMapper getSqlMapper(String sqlKey ){
        return sqlConfig.getSqlMapper(sqlKey) ;
    }

    @Override
    public void afterPropertiesSet() {
        if (getSqlConfig() == null) {
            throw new IllegalArgumentException("Property 'sqlConfig' is required");
        }
    }
    protected abstract String getParsedSql(String sqlKey, Map<String, Object> map);

    @Override
    public String getSql(String sqlKey, Map<String, Object> map) {
        String parsedSql = getParsedSql(sqlKey,map) ;
        return sqlConvert(parsedSql,map);
    }

    private String sqlConvert(String sql, Map  qryMap) {
        // replace #param to value
        if (qryMap != null && !qryMap.isEmpty()) {
            List<String> params = getReplaceParameterList(sql);
            for (String param : params) {
                sql = StringUtils.replaceOnce(sql, "#" + param,
                        ObjectUtils.toString(qryMap.get(param)));
            }
        }
        return sql;
    }

    /**
     * sql ( select * from table where user_id = #userId ) #userId will be
     * replaced into list as param
     *
     * @param sql
     * @return
     */
    private List<String> getReplaceParameterList(String sql) {
        String regex = "\\#(\\w+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(sql);
        List<String> params = new ArrayList<String>();
        while (matcher.find())
            params.add(matcher.group(1));
        return params;
    }

}